<?php
/*
   GMLP_FUNC_LS.PHP - a special "block" function

In GMLP, the input text is an array of lines, and a "block" is a number of 
lines enclosed between a "begin" line and an "end" line, both of which are 
defined by regular expresions; for example:

	[0] Line outside of block.
	[1] <block>
	[2] Lines inside block.
	[3] </block>
	[4] Line outside of block.

The convert code shifts the input text one line at a time and detects the 
block by the regular expression on the current line.

If a block definition has a member named 'function' that function will be 
called with a reference to the input array and a reference to the line that 
began the block:

	"<block>"			begin line

	[0] Lines inside block.		input text
	[1] </block>
	[2] Line outside of block.

For a special block function to work is MUST shift the array until the "end" 
line, keeping it's block to work with. So, at one point the data will look 
like this:

	"<block>"			begin line
	"</block>"			end line

	[0] Lines inside block.		block text

	[0] Line outside of block.	input text

Optionally, the function can place the end line back (unshift) into the input 
text. (If the function wanted to perform the end regular expression test 
before the shift so as to not have to unshift, that would of course be 
perfectly fine, however, the function MUST use array_shift() on the input 
text.)

The processed block text is returned in the start line reference (a string), 
which may be non-intuitive but the begin line is of no use to the caller and 
overloading it eliminates an extra variable.
*/

/* gmlp_ls_block - "smarter" version of gmlp_convert_block */

// UPDATE: This code it turns out ain't that smart, as it gets confused 
// easily. I leave it in soley as example code.

function gmlp_ls_block(&$data, &$s) {

	$end = '/(^\S+|^$)/';

	// start with the begin line
// NOT ALL code needs to use the starting line in the text it is formatting,
// just one LIKE THIS that uses it as part of the text
	$block[] = $s."\n";

	// gather entire block
	while (($_ = array_shift($data)) !== NULL) {
		if (preg_match($end,$_))
			break;
		$block[] = $_."\n";
	}

	// put back what ended the block
	array_unshift($data,$_);
// putting back the end line may not seem right, but it is the only way this 
// will work, otherwise, a line of text could be lost - NOT ALL code to attach 
// to the 'function' block array member has to do that, just one LIKE THIS that 
// ends on a line that needs to be put back into the text

// (Yeah, a bit lame. In my defense, it seemed like a good idea at the time.)
	$type = 0;
	if ($block[0][0] == '[' || preg_match('/^[a-z]+\s+=\s+/',$block[0]))
		$type = 1;
	elseif (strpos($block[0],'$') !== FALSE || strpos($block[0],'=>') !== FALSE)
		$type = 2;
	elseif (strpos($block[0],'php:') !== FALSE) {
		$type = 2;
		array_shift($block);
	}
	elseif (strpos($block[0],'<?php') !== FALSE)
		$type = 3;

	// "trim" each line first
	foreach ($block as &$b)
		gmlp_line($b);

	// convert to string (directly using the "return value")
	$s = implode($block);

	if ($type == 3)
		$s = gmlp_highlightstr(rtrim($s));
	else
	if ($type == 2)
		$s = gmlp_highlightstr_php(rtrim($s));
	else
	if ($type == 1)
		$s = gmlp_ini($s);
	else {
		$s = htmlentities($s);
		$s = '<pre>'."\n".$s.'</pre>';
	}

	$s .= "\n";
}
